package cw.itsource.queue;

import com.rabbitmq.client.*;
import cw.itsource.utils.ConnectionUtil;

import java.io.IOException;

/**
 * 编写消费者的示例代码
 */
public class MainConsumerQuick {
    private static final String QUEUE = "hello-queue";

    public static void main(String[] args) throws Exception {
        //1. 创建一个连接
        Connection connection = ConnectionUtil.getConnection();
        //2. 获取一个通道
        final Channel channel = connection.createChannel();
        //TODO  消费在处理消息，每次只拿1条消息，处理完之后两从通道（队列）中取
        channel.queueDeclare(QUEUE, true, false, false, null);
        //TODO  这种效果，必须 消息确认机制ACK 为手动确认，如果是自动确认，设置将无效
        channel.basicQos(1);
        //3. 创建一个消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
            /**
             * 消费者接收消息调用此方法
             * @param consumerTag 消费者的标签，在channel.basicConsume()去指定
             * @param envelope 消息包的内容，可从中获取消息id，消息routingkey，交换机，消息和重传标志
            (收到消息失败后是否需要重新发送)
             * @param properties
             * @param body
             */

            @Override //这个方法，就是用于监听通道，并处理通道中的消息（自动处理）
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "utf8"); //将字节数组转为字符串

                System.out.println(">>>【快消费者】：" + message);

                //TODO 进行业务逻辑的处理
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //进行手动应答
                long deliveryTag = envelope.getDeliveryTag();
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        //4. 将消费者绑定到队列上
        /**
         * 监听队列String queue, boolean autoAck,Consumer callback
         * 参数明细
         * 1、队列名称
         * 2、是否自动回复，设置为true为表示消息接收到自动向mq回复接收到了，mq接收到回复会删除消息，设置
         为false则需要手动回复。  参数值为true:自动确认；false:手动确认（ACK机制）
         * 3、消费消息的方法，消费者接收到消息后调用此方法
         */
        channel.basicConsume(QUEUE, false, defaultConsumer); //当代码执行到这一行，即表示消费者已经处理【启动】状态


    }
}
